"""
成员运算符和身份运算符
学习目标：
1. 掌握成员运算符 in 和 not in 的使用
2. 理解身份运算符 is 和 is not 的使用
3. 区分 == 和 is 的区别
"""

# ==================== 1. 成员运算符 in ====================
print("=" * 50)
print("1. 成员运算符 in")
print("=" * 50)

# 在字符串中查找
text = "Hello, Python!"
print(f"字符串：'{text}'")
print(f"'Python' in text: {'Python' in text}")
print(f"'Java' in text: {'Java' in text}")
print(f"'o' in text: {'o' in text}")

print()

# 在列表中查找
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
print(f"列表：{fruits}")
print(f"'苹果' in fruits: {'苹果' in fruits}")
print(f"'西瓜' in fruits: {'西瓜' in fruits}")

print()

# 在元组中查找
numbers = (1, 2, 3, 4, 5)
print(f"元组：{numbers}")
print(f"3 in numbers: {3 in numbers}")
print(f"6 in numbers: {6 in numbers}")

print()

# 在字典中查找（查找键）
student = {"name": "张三", "age": 18, "grade": "高三"}
print(f"字典：{student}")
print(f"'name' in student: {'name' in student}")
print(f"'score' in student: {'score' in student}")
print(f"'张三' in student: {'张三' in student}")  # 注意：默认查找键，不是值

print()

# 在集合中查找
tags = {"Python", "编程", "学习", "技术"}
print(f"集合：{tags}")
print(f"'Python' in tags: {'Python' in tags}")
print(f"'Java' in tags: {'Java' in tags}")

print()

# ==================== 2. 成员运算符 not in ====================
print("=" * 50)
print("2. 成员运算符 not in")
print("=" * 50)

# not in 表示不在其中
text = "Python is awesome"
print(f"字符串：'{text}'")
print(f"'Java' not in text: {'Java' not in text}")
print(f"'Python' not in text: {'Python' not in text}")

print()

fruits = ["苹果", "香蕉", "橙子"]
print(f"列表：{fruits}")
print(f"'西瓜' not in fruits: {'西瓜' not in fruits}")
print(f"'苹果' not in fruits: {'苹果' not in fruits}")

print()

# ==================== 3. 成员运算符的实战应用 ====================
print("=" * 50)
print("3. 实战：用户名验证")
print("=" * 50)

# 禁用的用户名列表
forbidden_names = ["admin", "root", "system", "test"]
username = "alice"

print(f"禁用用户名：{forbidden_names}")
print(f"输入用户名：{username}")

if username in forbidden_names:
    print("❌ 该用户名已被禁用，请换一个")
else:
    print("✅ 用户名可用")

print()

# ==================== 4. 实战：权限检查 ====================
print("=" * 50)
print("4. 实战：权限检查")
print("=" * 50)

# 管理员列表
admins = ["admin", "张三", "李四"]
current_user = "王五"

print(f"管理员列表：{admins}")
print(f"当前用户：{current_user}")

if current_user in admins:
    print("✅ 您有管理员权限")
else:
    print("❌ 您没有管理员权限")

print()

# ==================== 5. 实战：关键词过滤 ====================
print("=" * 50)
print("5. 实战：敏感词过滤")
print("=" * 50)

# 敏感词列表
sensitive_words = ["暴力", "色情", "赌博"]
comment = "这是一条正常的评论内容"

print(f"敏感词列表：{sensitive_words}")
print(f"评论内容：{comment}")

# 检查是否包含敏感词
has_sensitive = False
for word in sensitive_words:
    if word in comment:
        has_sensitive = True
        print(f"⚠️ 评论包含敏感词：{word}")
        break

if not has_sensitive:
    print("✅ 评论审核通过")

print()

# ==================== 6. 身份运算符 is ====================
print("=" * 50)
print("6. 身份运算符 is")
print("=" * 50)

# is 检查两个变量是否指向同一个对象
a = [1, 2, 3]
b = a  # b 指向 a 所指向的对象
c = [1, 2, 3]  # c 是一个新对象，虽然内容相同

print(f"a = {a}")
print(f"b = {b}")
print(f"c = {c}")
print()

print(f"a is b: {a is b}")  # True，指向同一对象
print(f"a is c: {a is c}")  # False，不同对象
print(f"a == c: {a == c}")  # True，内容相同

print()
print("💡 is 比较的是对象的身份（内存地址）")
print("💡 == 比较的是对象的值（内容）")

print()

# ==================== 7. 身份运算符 is not ====================
print("=" * 50)
print("7. 身份运算符 is not")
print("=" * 50)

a = [1, 2, 3]
b = [1, 2, 3]

print(f"a = {a}")
print(f"b = {b}")
print(f"a is not b: {a is not b}")  # True，不是同一对象
print(f"a != b: {a != b}")  # False，内容相同

print()

# ==================== 8. == vs is 的区别 ====================
print("=" * 50)
print("8. == 和 is 的区别")
print("=" * 50)

# 案例1：列表
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1

print("【列表】")
print(f"list1 == list2: {list1 == list2}")  # True，内容相同
print(f"list1 is list2: {list1 is list2}")  # False，不同对象
print(f"list1 is list3: {list1 is list3}")  # True，同一对象

print()

# 案例2：小整数（-5到256）Python会缓存
num1 = 100
num2 = 100

print("【小整数（-5到256）】")
print(f"num1 = {num1}, num2 = {num2}")
print(f"num1 == num2: {num1 == num2}")  # True
print(f"num1 is num2: {num1 is num2}")  # True，Python优化

print()

# 案例3：大整数
big1 = 1000
big2 = 1000

print("【大整数】")
print(f"big1 = {big1}, big2 = {big2}")
print(f"big1 == big2: {big1 == big2}")  # True
print(f"big1 is big2: {big1 is big2}")  # 可能是False（取决于Python实现）

print()

# 案例4：字符串（短字符串会被intern）
str1 = "hello"
str2 = "hello"

print("【字符串】")
print(f"str1 = '{str1}', str2 = '{str2}'")
print(f"str1 == str2: {str1 == str2}")  # True
print(f"str1 is str2: {str1 is str2}")  # True，字符串驻留

print()

# ==================== 9. 使用 id() 查看对象标识 ====================
print("=" * 50)
print("9. 使用 id() 查看对象标识")
print("=" * 50)

a = [1, 2, 3]
b = a
c = [1, 2, 3]

print(f"a 的内存地址：{id(a)}")
print(f"b 的内存地址：{id(b)}")
print(f"c 的内存地址：{id(c)}")
print()

print(f"id(a) == id(b): {id(a) == id(b)}")  # True
print(f"id(a) == id(c): {id(a) == id(c)}")  # False

print()
print("💡 is 等价于比较 id()")
print(f"   a is b 等价于 id(a) == id(b)")

print()

# ==================== 10. 实战：None 的检查 ====================
print("=" * 50)
print("10. 实战：None 值检查")
print("=" * 50)

# None 是Python的特殊单例对象
value = None

print(f"value = {value}")
print()

# 推荐的检查方式：使用 is
if value is None:
    print("✅ 推荐写法：value is None")

# 不推荐但也能用
if value == None:
    print("⚠️ 可以工作但不推荐：value == None")

print()
print("💡 检查 None 应该使用 is 而不是 ==")

# 函数返回值检查
def get_user(user_id):
    """模拟查询用户，未找到返回None"""
    if user_id == 1:
        return {"name": "张三", "age": 18}
    return None

result = get_user(999)
if result is None:
    print("❌ 未找到用户")
else:
    print(f"✅ 找到用户：{result}")

print()

# ==================== 11. 实战：列表元素查找 ====================
print("=" * 50)
print("11. 实战：购物车商品查找")
print("=" * 50)

shopping_cart = [
    {"name": "Python书籍", "price": 89},
    {"name": "键盘", "price": 299},
    {"name": "鼠标", "price": 159}
]

search_item = "键盘"

print("购物车：")
for item in shopping_cart:
    print(f"  - {item['name']} ¥{item['price']}")

print(f"\n查找商品：{search_item}")

# 方法1：直接遍历
found = False
for item in shopping_cart:
    if search_item in item['name']:
        print(f"✅ 找到商品：{item['name']}，价格：¥{item['price']}")
        found = True
        break

if not found:
    print("❌ 未找到该商品")

print()

# ==================== 12. 实战：字符串子串检查 ====================
print("=" * 50)
print("12. 实战：邮箱格式检查")
print("=" * 50)

email = "user@example.com"

print(f"邮箱地址：{email}")
print()

# 简单的邮箱格式检查
if "@" in email and "." in email:
    # 进一步检查
    at_pos = email.index("@")
    if at_pos > 0 and at_pos < len(email) - 1:
        print("✅ 邮箱格式基本正确")
    else:
        print("❌ 邮箱格式错误：@ 位置不对")
else:
    print("❌ 邮箱格式错误：缺少 @ 或 .")

print()

# ==================== 13. 实战：文件类型检查 ====================
print("=" * 50)
print("13. 实战：文件类型检查")
print("=" * 50)

filename = "document.pdf"

# 支持的文档类型
supported_types = [".pdf", ".doc", ".docx", ".txt"]

print(f"文件名：{filename}")
print(f"支持的类型：{supported_types}")
print()

# 检查文件扩展名
is_supported = False
for ext in supported_types:
    if filename.endswith(ext):  # 也可以用 in，但 endswith 更精确
        is_supported = True
        print(f"✅ 文件类型受支持：{ext}")
        break

if not is_supported:
    print("❌ 不支持的文件类型")

print()

# ==================== 14. 实战：标签匹配 ====================
print("=" * 50)
print("14. 实战：文章标签匹配")
print("=" * 50)

article_tags = {"Python", "编程", "教程", "基础"}
user_interests = {"Python", "机器学习", "数据分析"}

print(f"文章标签：{article_tags}")
print(f"用户兴趣：{user_interests}")
print()

# 找出共同标签
common_tags = []
for tag in user_interests:
    if tag in article_tags:
        common_tags.append(tag)

if common_tags:
    print(f"🎯 推荐理由：匹配标签 {common_tags}")
else:
    print("📌 没有匹配的标签")

print()

# ==================== 15. 综合实战：表单验证 ====================
print("=" * 50)
print("15. 综合实战：用户注册表单验证")
print("=" * 50)

# 用户输入
username = "alice123"
email = "alice@example.com"
age = 20

# 验证规则
print("【表单验证】")
errors = []

# 1. 用户名检查
forbidden_chars = ["!", "@", "#", "$", "%"]
has_forbidden = False
for char in forbidden_chars:
    if char in username:
        has_forbidden = True
        break

if has_forbidden:
    errors.append("用户名包含非法字符")
elif len(username) < 3:
    errors.append("用户名至少3个字符")

# 2. 邮箱检查
if "@" not in email or "." not in email:
    errors.append("邮箱格式不正确")

# 3. 年龄检查
if age is None:
    errors.append("年龄不能为空")
elif age < 18:
    errors.append("必须年满18岁")

# 显示结果
print(f"用户名：{username}")
print(f"邮箱：{email}")
print(f"年龄：{age}")
print()

if errors:
    print("❌ 验证失败：")
    for error in errors:
        print(f"  - {error}")
else:
    print("✅ 验证通过，注册成功！")

print()

# ==================== 总结 ====================
print("=" * 50)
print("✨ 成员运算符和身份运算符总结")
print("=" * 50)
print("""
【成员运算符】
1. in：检查元素是否在序列中
2. not in：检查元素是否不在序列中

适用于：字符串、列表、元组、字典（键）、集合

常见用途：
- 查找元素
- 权限检查
- 关键词过滤
- 数据验证

【身份运算符】
1. is：检查两个变量是否指向同一对象
2. is not：检查两个变量是否不指向同一对象

💡 is vs ==：
- is：比较对象身份（内存地址）
- ==：比较对象的值（内容）

最佳实践：
- 检查 None 使用 is：if x is None
- 检查值相等使用 ==：if x == y
- 检查两个变量是否是同一对象用 is

⚠️ 注意事项：
- 字典用 in 默认检查键，不是值
- 小整数和字符串可能被Python缓存
- None 是单例对象，用 is 检查
""")
print("=" * 50)

